package org.erepublik.company;

import java.util.ArrayList;

import org.erepublik.company.product.ProductDesign;
import org.erepublik.company.searchCriteria.CompanySimulatorFetch;
import org.erepublik.company.searchCriteria.ECompanyCalculatorProductType;
import org.erepublik.company.searchCriteria.EQuality;
import org.erepublik.company.searchCriteria.ERawRegion;
import org.erepublik.company.searchCriteria.EWorkerWellness;
import org.erepublik.company.service.IProductsService;
import org.erepublik.company.service.JSONCountryDataProvider;
import org.erepublik.company.service.XmlVatService;
import org.erepublik.company.utils.Utils;
import org.hibernate.impl.CriteriaImpl.CriterionEntry;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class CompanyForSale implements JSONAble, Comparable<CompanyForSale> {

    public String getRegionName() {
        return regionName;
    }
    public void setRegionName(String regionName) {
        this.regionName = regionName;
    }

    private int id;
    private ECountry country;
    private String regionName;
    private ERawRegion rawRegion = ERawRegion.HIGH;
    public void setRawRegion(ERawRegion rawRegion) {
        this.rawRegion = rawRegion;
    }

    private License[] licenses;
    private double price;
    private double estimatedPrice;
    private String name;
    private EProductType productType;
    private int quality;
    private int employesNumber;
    private int stockSize;
    private double rawSize;
    private ProductDesign producrDesign;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    public License[] getLicenses() {
        return licenses;
    }
    public void setLicenses(License[] licenses) {
        this.licenses = licenses;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public double getEstimatedPrice() {
        return estimatedPrice;
    }
    public void setEstimatedPrice(double estimatedPrice) {
        this.estimatedPrice = estimatedPrice;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public EProductType getProductType() {
        return productType;
    }
    public void setProductType(EProductType productType) {
        this.productType = productType;
    }
    public int getQuality() {
        return quality;
    }
    public void setQuality(int quality) {
        this.quality = quality;
    }
    public int getEmployesNumber() {
        return employesNumber;
    }
    public void setEmployesNumber(int employesNumber) {
        this.employesNumber = employesNumber;
    }
    public int getStockSize() {
        return stockSize;
    }
    public void setStockSize(int stockSize) {
        this.stockSize = stockSize;
    }
    public double getRawSize() {
        return rawSize;
    }
    public void setRawSize(double d) {
        this.rawSize = d;
    }
    public ProductDesign getProducrDesign() {
        return producrDesign;
    }
    public void setProducrDesign(ProductDesign producrDesign) {
        this.producrDesign = producrDesign;
    }

    
    
    public void setCountry(ECountry country) {
        this.country = country;
    }
    
    @Override
    public ECountry getCountry() {
        return country;
    }
    
    
    @Override
    public JSONObject toJSONObject() throws JSONException {
        
        JSONObject object = new JSONObject();
        object.put("id", id);
        object.put("country", country);
        object.put("price", price);
        object.put("name", name);
        object.put("productType", productType);
        object.put("quality", quality);
        object.put("employesNumber", employesNumber);
        object.put("stockSize", stockSize);
        object.put("rawSize", rawSize);
        object.put("licenses", licencesToJSONArray(licenses));
        object.put("regionName", regionName);
        if (getProductType().isRaw())
            object.put("rawRegion", rawRegion.toString());
        
        return object;
    }
    

    
    public static CompanyForSale getCompanyForSaleFromJSON(JSONObject object) throws NumberFormatException, JSONException {
        
        CompanyForSale companyForSale = new CompanyForSale();
        companyForSale.setId( Integer.parseInt( object.get("id").toString()) );
        companyForSale.setCountry( ECountry.valueOf( object.get("country").toString() ) );
        companyForSale.setPrice( readDoubleFromJSON( object.get("price") )  );
        companyForSale.setEmployesNumber( Integer.parseInt( object.get("employesNumber").toString()) );
        companyForSale.setName( object.get("name").toString() );
        companyForSale.setProductType( EProductType.valueOf( object.get("productType").toString() ) );
        companyForSale.setQuality( Integer.parseInt( object.get("quality").toString()) );
        companyForSale.setEmployesNumber( Integer.parseInt( object.get("employesNumber").toString()) );
        companyForSale.setStockSize( Integer.parseInt( object.get("stockSize").toString())  );
        companyForSale.setRawSize( readDoubleFromJSON( object.get("rawSize") )  );
        companyForSale.setLicenses( readLicensesFromJSONArray( object.getJSONArray("licenses") )  );
        companyForSale.setRegionName( object.getString("regionName")  );
        
        if (companyForSale.getProductType().isRaw() )
            companyForSale.setRawRegion( ERawRegion.valueOf(object.getString("rawRegion"))  );
        
        return companyForSale;
    }
    
 
    
    
    private static License[] readLicensesFromJSONArray(JSONArray object) {
        ArrayList<License> licenses = new ArrayList<License>();
        try {
            for (int i=0; i < object.length(); i++) {
                JSONObject json = object.getJSONObject(i);
                License license = new License();
                license.setActive( json.getBoolean("active") );
                license.setCountry( ECountry.valueOf( json.getString("country") ) );
                licenses.add(license);
            } 
        }
        catch (JSONException e) {
            e.printStackTrace();
        }
        
        
        return licenses.toArray(new License[0]);
    }
    
    private JSONArray licencesToJSONArray(License[] licenses) {
        JSONArray jsonArray = new JSONArray();
        
        try {
            for (int i=0; i < licenses.length; i++) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("active", licenses[i].isActive());
                jsonObject.put("country", licenses[i].getCountry());
                jsonArray.put(jsonObject);
            }
        }
        catch (JSONException e) {
            e.printStackTrace();
        }
        
        return jsonArray;
    }
    
    
    public ERawRegion getRawRegion() {
        return rawRegion;
    }
    
    public String getRawRegionDescription() {
        if (!productType.isRaw())
            throw new IllegalArgumentException("Nieprawidlowy typ produktu?!");
        else {
            if (rawRegion == ERawRegion.HIGH)
                return "(<font style=\"color: #007700\">High region</font>)";
            if (rawRegion == ERawRegion.MEDIUM)
                return "(<font style=\"color: #777700\">Medium region</font>)";            
            if (rawRegion == ERawRegion.LOW)
                return "(<font style=\"color: #770000\">Low region</font>)";       
            return "";
        }
    }
    
    
    private static double readDoubleFromJSON(Object object) {
        if (object instanceof Integer)
            return (Integer)object ;
        else
            return (Double)object ;
    }
    
    @Override
    public int compareTo(CompanyForSale o) {
        double diff = getPrice() - o.getPrice();
        if (diff<0)
            return -1;
        if (diff>0)
            return 1;
        return 0;
    }
  
    private IProductsService productService;
    private XmlVatService vatService;
    private JSONCountryDataProvider dataService;
    public void setServices(IProductsService productService, XmlVatService vatService, JSONCountryDataProvider dataService) {
        this.productService = productService;
        this.vatService = vatService;
        this.dataService = dataService;
    }
    private CompanyCalculator calculator = null;
    public double getDailyProfit() {
        
        if (productType==EProductType.HOSPITAL || productType==EProductType.DEFENSE_SYSTEM )
            return 0;
        
        if (calculator==null) {
            CompanySimulatorFetch criteria = new CompanySimulatorFetch();
            criteria.setCountry(getCountry());
            criteria.setProductType(ECompanyCalculatorProductType.valueOf( productType.toString() )  );
            criteria.setQuality(EQuality.valueOf( "Q"+quality ));
            if (criteria.getProductType().getProductType().isRaw())
                criteria.setRawRegion( getRawRegion() );
            else
                criteria.setRawRegion(ERawRegion.HIGH);
            criteria.setWorkerWellness(EWorkerWellness.W90);
            calculator = new CompanyCalculator( productService, vatService, criteria);
            calculator.calculateProfit();
        }
        
        return Utils.round(calculator.getDailyProfit() * dataService.getCountryData(getCountry()).getGoldForCurrency() , 2);
    }
    
    
}
